<?php
namespace App\Crawlers;

use App\Models\MovieBaseInfo;
use App\Models\Movie;
use App\Models\Star;
use QL\QueryList;
use QL\Ext\Chrome;
use Illuminate\Support\Str;

class MovieInfoCrawler {

    public function get($id) {
        // 抓取页面
        $url = config('services.oss.douban.url') . '/' . $id;
        $ql = QueryList::get($url);
        $result = [];
        // 采集电影名称
        $result['name'] = $ql->find('#content > h1 > span[property]')->text();
        $result['introduction'] = $ql->find( '.indent > span[property]')->html();
        $info = $ql->find('#info')->html();
        if(empty($result['name']) && empty($info)) return false;
        $result['area'] = $this->getArea($info);
        $result['language'] = collect($this->getLanguage($info))->toJson();
        $result['score'] = (float) $ql->find( '.rating_num')->text();
        $result['score_people'] = (int) $this->getScorePeople($ql);
        $result['cover'] = $ql->find( '.nbgnbg > img')->attr('src');
        $result['info'] = $info;
        $result['directors'] = $this->getDirectors($info);
        $result['authors'] = $this->getAuthors($info);
        $result['actors'] = $this->getActors($info);
        $result['categories'] = $this->getCategories($info);
        $result['published_at'] = $this->getPublishedAt($info);
        $result['year'] = $this->getYear($ql);
        $result['runtime'] = (int) $this->getRuntime($info);
        $result['outher_name'] = $this->getOutherName($info);
        $result['short_name'] = $this->getShortName($ql);
        $result['imdb'] = $this->getImdb($info);
        $result['douban_id'] = $id;
        return $result;
    }

    protected function getShortName($ql)
    {
        $title = $ql->find('title')->text();
        return trim(str_replace(' (豆瓣)', '', $title));
    }
    protected function getImdb($info)
    {
        $ql = QueryList::html($info);
        $imdb = $ql->find( 'a:last[rel=nofollow]')->text();
        if (Str::startsWith($imdb, 'tt')) return $imdb;
        else return '';
    }
    protected function getArea($info)
    {
        $preg = preg_match( '/<span class="pl">制片国家\/地区:<\/span>(.*)<br><span class="pl">/iUs', $info, $res);
        if($preg) return trim($res[1]);
        else return '';
    }
    protected function getScorePeople($ql)
    {
        return $ql->find('span[property=v:votes]')->text();
    }
    protected function getCategories($info)
    {
        $ql = QueryList::html($info);
        return $ql->rules([
            // 导演
            'category' => [ 'span[property=v:genre]', 'text'],
        ])->queryData();
    }
    protected function getLanguage($info)
    {
        $preg = preg_match( '/<span class="pl">语言:<\/span> (.*)<br><span class="pl">/iUs', $info, $res);
        if ($preg) {
            $language = trim($res[1]);
            if (Str::is('*/*', $language)) {
                return explode(' / ', $language);
            }
            return [$language];
        }
        else return [];
    }
    protected function getDirectors($info = '')
    {
        $ql = QueryList::html($info);
        return $ql->rules([
            // 导演
            'directors_name' => [ 'span.attrs a[rel=\'v:directedBy\']', 'text'],
            'directors_id' => [ 'span.attrs a[rel=\'v:directedBy\']', 'href', '', function ($url) {
                if (Str::is('/celebrity/*', $url)) return trim(Str::after($url, '/celebrity/'), '/');
                else return 0;
            }],
        ])->queryData();
    }
    protected function getAuthors($info)
    {
        $ql = QueryList::html($info);
        return $ql->rules([
            // 编剧
            'author_name' => [ 'span.attrs a:not([rel])', 'text'],
            'author_id' => ['span.attrs a:not([rel])', 'href', '', function ($url) {
                if (Str::is('/celebrity/*', $url)) return trim(Str::after($url, '/celebrity/'), '/');
                else return 0;
            }],
        ])->queryData();
    }
    protected function getActors($info)
    {
        $ql = QueryList::html($info);
        return $ql->rules([
            'actor_name' => [ 'span.actor span.attrs a[rel=\'v:starring\']', 'text'],
            'actor_id' => [ 'span.actor span.attrs a[rel=\'v:starring\']', 'href', '', function ($url) {
                if (Str::is( '/celebrity/*', $url)) return trim(Str::after($url, '/celebrity/'), '/');
                else return 0;
            }],
        ])->queryData();
    }
    protected function getPublishedAt($info)
    {
        $ql = QueryList::html($info);
        $published_at = $ql->rules([
            'published_at' => [ 'span[property=v:initialReleaseDate]', 'content']
        ])->queryData();
        return collect($published_at)->toJson();
    }

    protected function getYear($ql)
    {
        $year = $ql->find('#content h1 span.year')->text();
        return trim($year, ')(');
    }

    protected function getRuntime($info)
    {
        return QueryList::html($info)->find('span[property=v:runtime]')->attr('content');
    }

    protected function getOutherName($info)
    {
        $preg = preg_match( '/<span class="pl">又名:<\/span>(.*)<br>/iUs', $info, $res);
        if ($preg) return trim(trim($res[1]), '<br>');
        else return '';
    }
}
